package p.sunmes.les.actor;

import java.lang.reflect.Field;

import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Scaling;

public class HpBar extends Image {

	protected int maxWidth;

	protected float max;
	protected float targetValue;
	protected float currentValue;
	protected float changeValue;
	protected TextureRegion region;

	protected Field imageWidth;

	protected float animationDelay = 1;

	public HpBar(TextureRegion region) {
		TextureRegion tr = new TextureRegion(region);
		setDrawable(new TextureRegionDrawable(tr));
		setScaling(Scaling.stretch);
		setAlign(Align.center);
		setSize(getPrefWidth(), getPrefHeight());
		setMaxValue();
		maxWidth = tr.getRegionWidth();
		this.region = tr;

		try {
			imageWidth = Image.class.getDeclaredField("imageWidth");
			imageWidth.setAccessible(true);
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}

	public void setMaxValue(float max, boolean isResetTarget) {
		this.max = max;
		if (isResetTarget) {
			this.targetValue = max;
			this.currentValue = max;
		}

		float per = currentValue / max;
		_setRegionWidth(maxWidth * per);

		setScaling(Scaling.none);
		setOrigin(Align.left);
	}

	/**
	 * max=1;
	 */
	public void setMaxValue() {
		setMaxValue(1, true);
	}

	public void setAnimationDelay(float dt) {
		animationDelay = dt;
	}

	private void _setRegionWidth(float p) {
		if (region == null) {
			return;
		}
		int pi = Math.round(p);
		if (region.getRegionWidth() != pi) {
			region.setRegionWidth(pi);
			try {
				imageWidth.set(this, p);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return;
	}

	public void updateBar(float delta) {
		if (region == null) {
			return;
		}
		if (changeValue == 0) {
			return;
		}
		if (max == 0) {
			max = 1;
			targetValue = 1;
		}
		if (animationDelay > 0) {
			currentValue += changeValue * (delta / animationDelay);
		} else {
			currentValue += changeValue;
		}
		if (changeValue < 0) {
			if (currentValue <= targetValue) {
				changeValue = 0;
				currentValue = targetValue;
			}
		} else { //>0   ///no need check ==0
			if (currentValue >= targetValue) {
				changeValue = 0;
				currentValue = targetValue;
			}
		}

		float per = currentValue / max;
		_setRegionWidth(maxWidth * per);
	}

	@Override
	public void act(float delta) {
		super.act(delta);
		updateBar(delta);
	}

	/**
	 * 
	 * @param percent  0-1f
	 */
	public void setPercent(float percent, boolean immediately) {
		if (percent > 1) {
			percent = 1;
		}
		if (percent < 0) {
			percent = 0;
		}
		targetValue = max * percent;
		if (immediately) {
			currentValue = targetValue;
			float pf = maxWidth * (currentValue / max);
			_setRegionWidth(pf);
		}
		changeValue = targetValue - currentValue;
	}

	public void setPercent(float percent) {
		setPercent(percent, false);
	}

	public void setCurrentValue(float current) {
		setCurrentValue(current, false);
	}

	public void setCurrentValue(float current, boolean immediately) {
		if (current > max) {
			current = max;
		}
		if (current < 0) {
			current = 0;
		}
		targetValue = current;
		if (immediately) {
			currentValue = targetValue;
			float pf = maxWidth * (currentValue / max);
			_setRegionWidth(pf);
		}
		changeValue = targetValue - currentValue;
	}

	public float getMaxValue() {
		return max;
	}

	public float getCurrentValue() {
		return targetValue;
	}

}
